# -*- coding: utf-8 -*-
import uuid
from typing import Optional, List

from sqlalchemy import or_, func
from sqlalchemy.orm import selectinload

from db.session import with_session
from db.models.files import AccidentCaseFile


@with_session
def db_get_ac_files(session, *, name_like: str = None, offset: int = 0, limit: int = 50):
    query = session.query(AccidentCaseFile) \
        .filter(AccidentCaseFile.is_delete.is_(False))
    if name_like:
        query = query.filter(AccidentCaseFile.name.ilike(f"%{name_like}%"))
    total = query.count()
    items = query.order_by(AccidentCaseFile.create_time.desc()).offset(offset).limit(limit).all()
    return items, total


@with_session
def db_get_ac_files_by_user_groups(session, user_group_ids, *, name_like: str = None, offset: int = 0, limit: int = 50):
    """根据用户组ID列表获取事故案例文件"""
    if not user_group_ids:
        return [], 0
    
    query = session.query(AccidentCaseFile) \
        .filter(AccidentCaseFile.is_delete.is_(False)) \
        .filter(
            or_(
                AccidentCaseFile.group_ids == [],  # 空数组表示所有用户可访问
                func.json_contains(AccidentCaseFile.group_ids, str(user_group_ids))  # 与用户组ID有交集
            )
        )
    if name_like:
        query = query.filter(AccidentCaseFile.name.ilike(f"%{name_like}%"))
    total = query.count()
    items = query.order_by(AccidentCaseFile.create_time.desc()).offset(offset).limit(limit).all()
    return items, total


@with_session
def db_get_ac_file_by_id(session, file_id: uuid.UUID):
    if isinstance(file_id, str):
        file_id = uuid.UUID(file_id)
    return session.query(AccidentCaseFile) \
        .filter(AccidentCaseFile.id == file_id) \
        .first()


@with_session
def db_get_ac_file_by_name(session, file_hash_name: str):
    return session.query(AccidentCaseFile) \
        .filter(AccidentCaseFile.hash_name == file_hash_name, AccidentCaseFile.is_delete.is_(False)) \
        .first()


@with_session
def db_get_ac_files_by_origin_name(session, name_like: str):
    if not name_like:
        return session.query(AccidentCaseFile).filter(AccidentCaseFile.is_delete.is_(False)).all()
    return session.query(AccidentCaseFile) \
        .filter(AccidentCaseFile.is_delete.is_(False)) \
        .filter(AccidentCaseFile.name.ilike(f"%{name_like}%")) \
        .all()


@with_session
def db_add_ac_file(
    session,
    user_id: int,
    hash_name: str,
    file_name: str,
    location: str,
    file_type: str,
    size: float,
    accident_level: Optional[str] = None,
    report_date: Optional[str] = None,
    related_company: Optional[str] = None,
    accident_abstract: Optional[str] = None,
    accident_type: Optional[int] = None,
):
    f = session.query(AccidentCaseFile).filter(AccidentCaseFile.hash_name == hash_name).first()
    if f:
        f.is_delete = False
        f.created_by = user_id
        f.name = file_name
        f.hash_name = hash_name
        f.location = location
        f.file_type = file_type
        f.file_size = size
        if accident_level is not None:
            f.accident_level = accident_level
        if report_date is not None:
            f.report_date = report_date
        if related_company is not None:
            f.related_company = related_company
        if accident_abstract is not None:
            f.accident_abstract = accident_abstract
        if accident_type is not None:
            f.accident_type = accident_type
        session.commit()
        return f, True
    new_file = AccidentCaseFile(
        created_by=user_id,
        name=file_name,
        hash_name=hash_name,
        location=location,
        file_type=file_type,
        file_size=size,
        accident_level=accident_level,
        report_date=report_date,
        related_company=related_company,
        accident_abstract=accident_abstract,
        accident_type=accident_type,
    )
    session.add(new_file)
    session.commit()
    return new_file, False


@with_session
def db_update_ac_file_delete_state(session, file_id: uuid.UUID, delete: bool):
    file = session.query(AccidentCaseFile).get(file_id)
    if not file:
        return None
    file.is_delete = delete
    session.commit()
    return True


@with_session
def db_update_ac_file_info(
    session,
    file_id: uuid.UUID,
    name: Optional[str] = None,
    accident_level: Optional[str] = None,
    report_date: Optional[str] = None,
    related_company: Optional[str] = None,
    accident_abstract: Optional[str] = None,
    accident_type: Optional[str] = None,
):
    file = session.query(AccidentCaseFile).get(file_id)
    if not file:
        return None
    if name is not None:
        file.name = name
    if accident_level is not None:
        file.accident_level = accident_level
    if report_date is not None:
        file.report_date = report_date
    if related_company is not None:
        file.related_company = related_company
    if accident_abstract is not None:
        file.accident_abstract = accident_abstract
    if accident_type is not None:
        file.accident_type = accident_type
    session.commit()
    return file


